<?php


namespace app\admin\service;

use app\admin\service\UsersService;
use app\common\exception\ForbiddenException;
use app\common\model\GroupModel;
use app\common\model\RoleModel;
use app\common\model\UsersModel;
use app\common\service\CacheWarmUp;
use app\common\service\Redis;

class RbacService
{
    public static $user_id;

    /**
     * 检查权限
     * @return bool|mixed|string
     * @throws \Exception
     *
     * @Author: Li Guo Xin <guoxinlee129@gmail.com>
     * @Date: 2020/7/27
     * @Time: 18:23
     */
    public static function checkPermissions($type = 'default')
    {
        //检测token是否有效
        $header = request()->header();
        switch ($type) {
            case 'admin':
                $key = 'admin_access_token';
                break;
            default:
                $key = 'access_token';
        }
        if (!isset($header[$key])) {
            throw new ForbiddenException(['msg' => '请输入令牌']);
        }
        $adminAccessToken = $header[$key];
        $userId           = Redis::getUserIdByAccessToken($adminAccessToken, $type);
        if (!$userId) {
            throw new ForbiddenException(['msg' => '令牌有误','code' => -2]);
        }

        //获取用户group_id
        $userModel = UsersModel::where('id',$userId)->field('group_id')->find();
        if (!$userModel) {
            throw new ForbiddenException(['code' => -2]);
        }
        #给token续时
        Redis::addExpireForAccessToken($adminAccessToken, $type);

        $app        = App('http')->getName();
        $controller = request()->controller();
        $action     = request()->action();
        $method     = request()->method();
        //user_id => group_id => role_ids
        $groupRoles   = self::getRBACGroupRole();
        $needRolesIds = [];
        foreach ($groupRoles as $groupRole) {
            #筛选出这个组的所有权限
            if ($groupRole['group_id'] == $userModel->getData('group_id')) {
                $needRolesIds[] = $groupRole['role_id'];
                $ownRole[]      = $groupRole;
            }
        }
        $pass    = false;
        $roles   = self::getRBACRole();
        $ownRole = [];#用户拥有的所有权限集合
        foreach ($needRolesIds as $needRoleId) {
            //筛选组内权限，如果是公共权限则跳过
            foreach ($roles as $role) {
                if ($needRoleId == $role['id'] | $role['common'] === '是') {
                    //公共权限 || 有权 => 放权
                    if (
                        $role['common'] === '是' ||
                        (
                            strtolower($role['app']) === strtolower($app) &&
                            strtolower($role['controller']) === strtolower($controller) &&
                            strtolower($role['action']) === strtolower($action) &&
                            strtolower($role['method']) === strtolower($method)
                        )
                    ) {
                        $ownRole[] = $role;
                        $pass      = true;
                    }
                }

            }

        }
            if (!$pass) {
            throw new ForbiddenException();
        }

        return ['user_id' => self::$user_id = $userId, 'roles' => $ownRole];
    }

    public static function getRbacGroup()
    {
        //缓存中没有，从mysql中读取
        //$data = Redis::tableGet('group');
        //if (!$data) {
        return CacheWarmUp::group();
        //}
        //return $data;
    }

    public static function getRBACRole()
    {
        //缓存中没有，从mysql中读取
        //$data = Redis::tableGet('role');
        //if (!$data) {
        return CacheWarmUp::role();
        //}
        //return $data;
    }

    public static function getRBACGroupRole()
    {
        //缓存中没有，从mysql中读取
        //$data = Redis::tableGet('group_role');
        //if (!$data) {
        return CacheWarmUp::group_role();
        //}
        //return $data;
    }

}